A computer system performs a power on self test (POST) procedure when it is initially turned on or reset in order to boot and configure itself for operation. POST is performed by a BIOS (Basic Input/Output System), or firmware, stored in a ROM (Read Only Memory) and executed by a processor within the computer system. Among other functions, POST includes initializing (configuring or programming) a memory subsystem of the computer system. The memory subsystem includes physical computer memory and a memory controller by which the physical computer memory is accessed. The physical computer memory includes one or more memory modules, such as SDRAM DIMMs (synchronized dynamic random access memory dual in-line memory modules). Each memory module includes an EEPROM (electrically erasable programmable ROM) or SPD (serial presence detect), which stores SPD data that identifies and describes the memory module. The EEPROM is a nonvolatile memory device, which can store data without losing the data during a system reset.
The initialization of the memory subsystem involves testing and sizing the computer memory (i.e. determining how much physical computer memory is present and useable) and configuring the memory controller to use the computer memory. To do so, the BIOS gathers type, size, speed and memory attributes from the EEPROMs of the memory modules and programs the memory controller accordingly.
Until the memory controller and memory modules are initialized, the memory subsystem cannot be used, so the computer system effectively has no useable memory. Once the memory controller has been configured, the BIOS will program a setting in the memory controller that triggers the memory controller to initialize the memory modules. Then the computer memory is capable of being used.
After the memory subsystem is initialized, it is possible to create, or initialize, variables and a software “stack” within the computer memory. The stack is commonly used in many programming functions, such as upon entering into and exiting from subroutines. Program code, or instructions, that use the stack are referred to as “stack-based.” The instructions by which the BIOS initializes the memory subsystem, however, must be “stackless,” since the stack cannot be created before the memory subsystem is initialized. Therefore, since the memory initialization instructions are stackless, among other limitations, they cannot include the convenient and simple “normal” method of using variables or using subroutines in which the contents of registers within the processor are saved to the stack upon entering a subroutine and restored to the registers upon exiting from the subroutine. Without the convenience of subroutines and variables, many of the instructions must be repeated within the firmware each time functions reoccur.
The stackless memory initialization instructions are limited to using the registers of the processor as the only available memory spaces. This limitation may not be significant for some processors that have over a hundred registers, but there are other processors that have a considerably smaller set of registers with which to work. The Opteron (TM) processor from AMD, for example, has only six registers. With so few registers, it is very important to be extremely careful how the registers are used. The stackless nature of the instructions operating on such processors, therefore, causes the memory initialization firmware to be relatively complex, detailed and lengthy to ensure that register contents are not lost during memory initialization. The complexity and length of the firmware, however, negatively impacts development cost and time incurred in generating and debugging the firmware.
For some computer systems that have multiple processors (multiple “nodes”), each processor is associated with its own memory subsystem. Upon reset, all of the memory subsystems within the computer system must be initialized. One of the processors, referred to as a “bootstrap” processor, performs all of the initializations, while the other processors remain temporarily inactive. The bootstrap processor surveys each node to discover each memory subsystem, reads all the SPD data from all the DIMMs for each node and programs the memory controller for each node. In this case, the stackless memory initialization instructions are even more complex, detailed and lengthy than in the single-processor case described above, since the instructions are not only stackless, but also must be able to handle multiple nodes.